/*******************************************************************************
 * Copyright (c) 2008 Sylvain Sicard.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Noel De Palma - initial API and implementation
 ******************************************************************************/
package fr.jade.reflex.control.attribute;

import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.factory.InstantiationException;

import fr.jade.fraclite.InitializationContext;
import fr.jade.fraclite.api.control.GenericAttributeController;
import fr.jade.fraclite.api.control.NoSuchAttributeException;
import fr.jade.fraclite.control.attribute.BasicGenericAttributeController;
import fr.jade.reflex.api.control.GenericAttributeNotificationController;
import fr.jade.reflex.api.control.ReflexController;
import fr.jade.reflex.util.Reflex;
import fr.jade.util.log.Logger;
import fr.jade.util.log.config.LogReflex;

/**
 * Provides an implementation of the {@link GenericAttributeController}
 * interface which manages the causal connection with the dual (i.e
 * meta/execution) level : Any attribute setting operation performed on the
 * current component is forwarded to the attribute controller of dual component.
 * 
 * In this implementation of Attribute Controller, attributes are stored in an
 * hashtable.
 * 
 * @author Noel De Palma
 * @author Sylvain Sicard
 * @contact noel.depalma@inrialpes.fr
 * 
 * Modified 1/6/5 F. Boyer: Merge this class with the
 * MetaGenericAttributeController class Use weaveableRC to get the
 * ReflexController of the current component
 */
public class ReflexGenericAttributeController extends BasicGenericAttributeController implements GenericAttributeNotificationController {

  protected ReflexController weaveableRC;

  public void initFcController(final InitializationContext ic) throws InstantiationException {
    super.initFcController(ic);
    weaveableRC = (ReflexController) ic.getInterface("reflex-controller");
  }

  protected GenericAttributeNotificationController getDualCtrl() {
    assert weaveableRC != null : "Component must have a ReflexController";
    Component dual = weaveableRC.getCmpRef();
    assert dual != null : "Component must have a dual";
    GenericAttributeNotificationController dualCtrl = null;
    try {
      dualCtrl = Reflex.getGenericAttributeNotificationController(dual);
    } catch (NoSuchInterfaceException ignored) {    }
    assert dualCtrl != null : "Dual component must have a GenericAttributeNotificationController";
    return dualCtrl;
  }


  /**
   * set the value of an attribute identified by its name and and then
   * notifies the dual level of the attribute setting.
   * 
   * @param name
   *            the name of the attribute to set.
   * @param value
   *            the value of the attribute.
   * @throws NoSuchAttributeException
   *             if the given attribute is unknow.
   */
  public void setAttribute(String name, String value) throws NoSuchAttributeException {
    setAttributeNotification(name, value);
    getDualCtrl().setAttributeNotification(name, value);
  }

  /**
   * Set the value of an attribute identified by its name.
   * 
   * @param name
   *            the name of the attribute to set.
   * @param value
   *            the value of the attribute.
   * @throws NoSuchAttributeException
   *             if the given attribute is unknown.
   */
  public void setAttributeNotification(String name, String value) throws NoSuchAttributeException {
    Logger.println(LogReflex.debug, "setAttribute " + name + "=" + value);
    super.setAttribute(name, value);
  }

}
